package com.poizon.infrastructure;

import cn.hutool.extra.spring.SpringUtil;
import com.poizon.infrastructure.cache.core.annoations.aop.CacheAspect;
import com.poizon.infrastructure.cache.core.domain.value.constants.CacheConstants;
import com.poizon.infrastructure.cache.core.repo.ICacheDbRepo;
import com.poizon.infrastructure.cache.core.strategy.del.ICacheDeleteStrategy;
import com.poizon.infrastructure.cache.core.strategy.del.impl.CacheDirectDeleteStrategy;
import com.poizon.infrastructure.cache.core.strategy.objType.ChooseCacheObjTypeStrategy;
import com.poizon.infrastructure.cache.core.strategy.objType.impl.CacheHashListStrategyImpl;
import com.poizon.infrastructure.cache.core.strategy.objType.impl.CacheHashObjStrategyImpl;
import com.poizon.infrastructure.cache.core.strategy.objType.impl.CacheStringListStrategyImpl;
import com.poizon.infrastructure.cache.core.strategy.objType.impl.CacheStringObjStrategyImpl;
import com.poizon.infrastructure.cache.core.strategy.through.ICacheThroughStrategy;
import com.poizon.infrastructure.cache.core.strategy.through.IPessimisticLockingStrategy;
import com.poizon.infrastructure.cache.core.util.ICacheUtil;
import com.poizon.infrastructure.cache.core.util.impl.CacheUtil;
import com.poizon.infrastructure.lock.core.util.ILock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

import java.util.Map;
import java.util.stream.Collectors;

/**
 * 自动配置/缓存
 */

@Slf4j
@Import({BannerPrint.class, CacheConstants.class})
public class CacheAutoConfig {

    /**
     * 注入缓存工具类实现
     */
    @Bean
    public ICacheUtil iCacheUtil(ILock iLock, ICacheDbRepo iCacheDbRepo) {
        log.info(">初始化缓存工具类实现");
        return new CacheUtil(iLock, iCacheDbRepo);
    }


    @Bean("CacheStringObjStrategyImpl")
    public ChooseCacheObjTypeStrategy chooseCacheObjTypeStrategy1(ICacheUtil iCacheUtil) {
        return new CacheStringObjStrategyImpl(iCacheUtil);
    }

    @Bean("CacheStringListStrategyImpl")
    public ChooseCacheObjTypeStrategy chooseCacheObjTypeStrategy2(ICacheUtil iCacheUtil) {
        return new CacheStringListStrategyImpl(iCacheUtil);
    }

    @Bean("CacheHashListStrategyImpl")
    public ChooseCacheObjTypeStrategy chooseCacheObjTypeStrategy3(ICacheUtil iCacheUtil) {
        return new CacheHashListStrategyImpl(iCacheUtil);
    }

    @Bean("CacheHashObjStrategyImpl")
    public ChooseCacheObjTypeStrategy chooseCacheObjTypeStrategy4(ICacheUtil iCacheUtil) {
        return new CacheHashObjStrategyImpl(iCacheUtil);
    }

    @Bean
    public CacheAspect cacheAspect() {
        log.info(">初始化缓存注解AOP");
        Map<String, ChooseCacheObjTypeStrategy> beansOfType = SpringUtil.getBeansOfType(ChooseCacheObjTypeStrategy.class);
        Map<String, ICacheDeleteStrategy> iCacheDeleteStrategyStringMap = SpringUtil.getBeansOfType(ICacheDeleteStrategy.class);
        Map<Class<? extends ICacheDeleteStrategy>, ICacheDeleteStrategy> iCacheDeleteStrategyClassMap = iCacheDeleteStrategyStringMap.values().stream().collect(Collectors.toMap(s -> s.getClass(), s -> s));
        return new CacheAspect(beansOfType.values(), iCacheDeleteStrategyClassMap);
    }

    /**
     * 缓存击穿策略注入
     */
    @Bean
    public ICacheThroughStrategy cacheThroughStrategy1(ICacheDbRepo iCacheDbRepo) {
        return new IPessimisticLockingStrategy(iCacheDbRepo);
    }

    @Bean
    public ICacheDeleteStrategy cacheDirectDeleteStrategy(ICacheDbRepo iCacheDbRepo) {
        return new CacheDirectDeleteStrategy(iCacheDbRepo);
    }
}
